﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace LostLib.Wikis
{
	public class Wiki: IDictionary<string, WikiPage>
	{
		public Wiki(string path)
		{
			_directory = path;

			if (!Directory.Exists(_directory))
				throw new DirectoryNotFoundException();
		}

		public static Wiki Create(string path)
		{
			Directory.CreateDirectory(path);

			return new Wiki(path);
		}

		string _directory;
		Dictionary<string, Cached<WikiPage>> _pages = new Dictionary<string,Cached<WikiPage>>();

		private Cached<WikiPage> CreatePageCache(string name)
		{
			Func<WikiPage> getter = () => new WikiPage(_directory + name + ".wiki");
			return new Cached<WikiPage>(getter);
		}

		public WikiPage this[string name]
		{
			get
			{
				Cached<WikiPage> page;

				if (_pages.TryGetValue(name, out page))
					return page;
				else
				{
					page = CreatePageCache(name);
					_pages.Add(name, page);

					return page;
				}
			}
			set
			{
				throw new InvalidOperationException();
			}
		}

		#region IDictionary<string,WikiPage> Members

		public void Add(string key, WikiPage value)
		{
			throw new InvalidOperationException();
		}

		public bool ContainsKey(string key)
		{
			return File.Exists(_directory + key + ".wiki");
		}

		public ICollection<string> Keys
		{
			get
			{
				return Directory.GetFiles(_directory, "*.wiki");
			}
		}

		public bool Remove(string key)
		{
			bool result = File.Exists(_directory + key + ".wiki");
			File.Delete(_directory + key + ".wiki");
			return result;
		}

		public bool TryGetValue(string key, out WikiPage value)
		{
			value = this[key];
			return true;
		}

		public ICollection<WikiPage> Values
		{
			get
			{
				throw new InvalidOperationException();
				// return Keys.Select(file => this[file]).ToList();
			}
		}
		#endregion

		#region ICollection<KeyValuePair<string,WikiPage>> Members

		public void Add(KeyValuePair<string, WikiPage> item)
		{
			throw new InvalidOperationException();
		}

		public void Clear()
		{
			foreach (var file in Directory.GetFiles(_directory, "*.wiki"))
				File.Delete(file);

			_pages.Clear();
		}

		public bool Contains(KeyValuePair<string, WikiPage> item)
		{
			throw new InvalidOperationException();
		}

		public void CopyTo(KeyValuePair<string, WikiPage>[] array, int arrayIndex)
		{
			throw new NotImplementedException();
		}

		public int Count
		{
			get { return Keys.Count; }
		}

		public bool IsReadOnly
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		public bool Remove(KeyValuePair<string, WikiPage> item)
		{
			throw new InvalidOperationException();
		}

		#endregion

		#region IEnumerable<KeyValuePair<string,WikiPage>> Members

		IEnumerable<KeyValuePair<string, WikiPage>> enumeratePairs()
		{
			foreach (var file in Keys)
				yield return new KeyValuePair<string, WikiPage>(file, this[file]);
		}

		public IEnumerator<KeyValuePair<string, WikiPage>> GetEnumerator()
		{
			return enumeratePairs().GetEnumerator();
		}

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		#endregion
	}
}
